package cn.dlc.com.stack;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Iterator;

/**
 * @author 邓立川
 * @date 2021/3/21 15:11
 * @desc 栈的实现
 */
@Data
public class Stack<T> implements Iterable<T>{

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    private class Node<T> {
        private T item;
        private Node next;
    }

    private Node<T> head;

    private int num;

    public Stack(){
        this.head = new Node<>(null,null);
        this.num = 0;
    }


    // 是否为空
    public boolean isEmpty(){
        return num == 0;
    }

    // 元素个数
    public int size(){
        return num;
    }

    // 压栈,head指向这个新压进去的元素
    public void push(T t) {

        // 原来首节点指向的元素
        Node<T> oldNode = head.getNext();

        // 新的元素
        Node<T> newNode = new Node<>(t, null);

        // 首节点指向新元素
        head.setNext(newNode);

        // 新元素指向原来的元素
        newNode.setNext(oldNode);

        this.num++;
    }

    // 首节点指向的元素出来
    public T pop(){
        // 原来首节点指向的元素
        Node<T> oldNode = head.getNext();
        if(oldNode == null) {
            return null;
        }

        // 新的下一个节点
        Node<T> newNode = oldNode.getNext();

        // 修改head的指向
        head.setNext(newNode);

        this.num--;

        return oldNode.getItem();
    }

    @Override
    public Iterator<T> iterator() {
        return new SIterator();
    }

    private class SIterator implements Iterator<T>{

        private Node<T> node;

        public SIterator(){
            // 从第一个元素开始
            this.node = head;
        }

        @Override
        public boolean hasNext() {
            return node.getNext() != null;
        }

        @Override
        public T next() {
            node = node.getNext();
            return node.getItem();
        }
    }

}
